import { createContext, useState, useEffect, useRef, useCallback } from 'react';
import type { ReactNode } from 'react';
import type { ConnectionStatus } from '../types';

interface WebSocketContextType {
  socket: WebSocket | null;
  connectionStatus: ConnectionStatus;
  realConnectionStatus: ConnectionStatus;
  sendMessage: (message: unknown) => void;
  connect: (url: string) => void;
  disconnect: () => void;
}

export const WebSocketContext = createContext<WebSocketContextType | undefined>(undefined);

export function WebSocketProvider({ children }: { children: ReactNode }) {
  const [socket, setSocket] = useState<WebSocket | null>(null);
  const [connectionStatus, setConnectionStatus] = useState<ConnectionStatus>('disconnected');
  const reconnectTimeoutRef = useRef<NodeJS.Timeout | null>(null);
  const reconnectAttemptsRef = useRef(0);
  const maxReconnectAttempts = 5;
  const reconnectDelayRef = useRef(1000);
  const urlRef = useRef<string>('');

  // 移除消息处理逻辑，让useChat直接处理WebSocket消息

  const connect = useCallback((url: string) => {
    urlRef.current = url;
    
    // 如果已经连接或正在连接，则不重复连接
    if (socket?.readyState === WebSocket.OPEN || connectionStatus === 'connecting') {
      return;
    }

    // 清理之前的连接
    if (socket) {
      socket.close();
      setSocket(null);
    }

    setConnectionStatus('connecting');
    
    try {
      const ws = new WebSocket(url);
      setSocket(ws);
      
      ws.onopen = () => {
        console.log('WebSocket connected, readyState:', ws.readyState);
        setConnectionStatus('connected');
        reconnectAttemptsRef.current = 0;
        reconnectDelayRef.current = 1000;
        
        // Send heartbeat every 30 seconds
        const heartbeatInterval = setInterval(() => {
          if (ws.readyState === WebSocket.OPEN) {
            ws.send(JSON.stringify({ type: 'heartbeat' }));
          } else {
            clearInterval(heartbeatInterval);
          }
        }, 30000);
      };
      
      // 不在这里处理消息，让useChat直接监听
      // ws.onmessage = handleMessage;
      
      ws.onclose = (event) => {
        console.log('WebSocket disconnected:', event.code, event.reason, 'wasClean:', event.wasClean);
        setConnectionStatus('disconnected');
        setSocket(null);
        
        // Auto-reconnect logic
        if (reconnectAttemptsRef.current < maxReconnectAttempts) {
          reconnectAttemptsRef.current++;
          console.log(`Attempting to reconnect... (${reconnectAttemptsRef.current}/${maxReconnectAttempts})`);
          
          reconnectTimeoutRef.current = setTimeout(() => {
            connect(urlRef.current);
          }, reconnectDelayRef.current);
          
          // Exponential backoff
          reconnectDelayRef.current = Math.min(reconnectDelayRef.current * 2, 30000);
        } else {
          console.log('Max reconnection attempts reached');
        }
      };
      
      ws.onerror = (error) => {
        console.error('WebSocket error:', error);
        console.error('WebSocket error details:', {
          readyState: ws.readyState,
          url: ws.url,
          protocol: ws.protocol
        });
        setConnectionStatus('disconnected');
      };
    } catch (error) {
      console.error('Failed to create WebSocket connection:', error);
      setConnectionStatus('disconnected');
    }
  }, []); // 移除依赖，避免无限重连

  const disconnect = useCallback(() => {
    if (reconnectTimeoutRef.current) {
      clearTimeout(reconnectTimeoutRef.current);
      reconnectTimeoutRef.current = null;
    }
    
    reconnectAttemptsRef.current = maxReconnectAttempts; // Prevent auto-reconnect
    
    if (socket) {
      socket.close();
      setSocket(null);
    }
    
    setConnectionStatus('disconnected');
  }, [socket]);

  // 获取真实的连接状态
  const getRealConnectionStatus = useCallback(() => {
    if (!socket) return 'disconnected';
    switch (socket.readyState) {
      case WebSocket.CONNECTING:
        return 'connecting';
      case WebSocket.OPEN:
        return 'connected';
      case WebSocket.CLOSING:
      case WebSocket.CLOSED:
        return 'disconnected';
      default:
        return 'disconnected';
    }
  }, [socket]);

  const sendMessage = useCallback((message: unknown) => {
    if (socket && socket.readyState === WebSocket.OPEN) {
      try {
        socket.send(JSON.stringify(message));
      } catch (error) {
        console.error('Failed to send message:', error);
      }
    } else {
      console.warn('WebSocket is not connected. ReadyState:', socket?.readyState, 'ConnectionStatus:', connectionStatus, 'Message not sent:', message);
      // 如果连接断开，更新连接状态
      if (socket && socket.readyState === WebSocket.CLOSED) {
        console.log('WebSocket is closed, updating connection status...');
        setConnectionStatus('disconnected');
      }
    }
  }, [socket, connectionStatus]);

  useEffect(() => {
    return () => {
      if (reconnectTimeoutRef.current) {
        clearTimeout(reconnectTimeoutRef.current);
      }
      if (socket) {
        socket.close();
      }
    };
  }, [socket]);

  const value = {
    socket,
    connectionStatus,
    realConnectionStatus: getRealConnectionStatus(),
    sendMessage,
    connect,
    disconnect,
  };

  return (
    <WebSocketContext.Provider value={value}>
      {children}
    </WebSocketContext.Provider>
  );
}

// useWebSocket hook is now in a separate file

export default WebSocketProvider;